/**
 * @Title：鼠标拖动选择行
 * @Version：1.0.0
 * @Auth：hoogl
 * @Date: 2022/04/13
 * @Time: 10:00
 *
 * 感谢王永山（wangys0927@163.com），我在他的基础上加工成此扩展插件！
 */

layui.define(['jquery'], function (exports) {
    "use strict";
    const $ = layui.jquery;

    layui.link(layui.cache.base + 'tableDragSelect/table_drag_select.css');

    Array.prototype.remove = function( item ){
        for( var i = 0 ; i < this.length ; i++ ){
            if( item == this[i] )
                break;
        }
        if( i === this.length )
            return;
        for( var j = i ; j < this.length - 1 ; j++ ){
            this[ j ] = this[ j + 1 ];
        }
        this.length--;
    };

    function clearEventBubble(evt){
        evt = evt || window.event;
        if (evt.stopPropagation) evt.stopPropagation(); else evt.cancelBubble = true;
        if (evt.preventDefault)  evt.preventDefault();  else evt.returnValue = false;
    }

    function posXY(event){
        event = event || window.event;
        var posX = event.pageX || (event.clientX +
            (document.documentElement.scrollLeft || document.body.scrollLeft));
        var posY = event.pageY || (event.clientY +
            (document.documentElement.scrollTop || document.body.scrollTop));
        return {x:posX, y:posY};
    }

    var _selectedRegions = {}, _timeoutID, _tableData = {}, _callbackFun = {};

    let RegionSelect = function(tableObj, callbackFun){
        this.version = '1.0.0';
        this.regions = {};
        this.data = _tableData;
        this.id = tableObj.config.id;
        this.selectId = null;

        let _self = this;

        if (isEmpty(_selectedRegions[_self.id])) {
            _selectedRegions[_self.id] = [];
        }

        _callbackFun[_self.id] = callbackFun;

        _self.regions[_self.id] = [];

        if (tableObj.config.url) {
            // 原done回调函数
            let _done = tableObj.config.done;

            tableObj.config.done = function (res, curr, count) {
                // 执行原done回调函数
                _done && _done();
                _self.init(tableObj.config);
                _self.data[_self.id] = res.data;
            };
        } else {
            _self.init(tableObj.config);
            _self.data[_self.id] = tableObj.config.data;
        }

        this.selectedClass = "selected";
        this.selectDiv = null;
        this.startX = null;
        this.startY = null;
    };

    RegionSelect.prototype.init = function(config) {
        let _self = this;

        var _regions = {};
        _regions[_self.id] = $('[lay-id="'+config.id+'"]').find('.layui-table-main tr');

        if(_regions[_self.id]  &&  _regions[_self.id].length > 0){

            $.each(_regions[_self.id], function (index, element) {
                var that = $(element);
                that.mousedown(function (evt) {
                    _self.selectId = $(this).closest(".layui-form").attr("lay-id");
                    if (evt.ctrlKey) {
                        if(that.hasClass(_self.selectedClass)){
                            that.removeClass(_self.selectedClass);
                            _selectedRegions[_self.id].remove(that);
                        } else {
                            that.addClass(_self.selectedClass);
                            _selectedRegions[_self.id].push(that);
                        }
                        _self.isSelect = true;
                    } else {
                        _regions[_self.id].removeClass(_self.selectedClass);
                        that.addClass(_self.selectedClass);
                        _selectedRegions[_self.id] = [];
                        _selectedRegions[_self.id].push(that);
                    }
                });
                _self.regions[_self.id].push(that);
            });
        }
    };

    RegionSelect.prototype.select = function(){
        var _self = this;
        // 鼠标按下
        $(".layui-table-body").mousedown(function(evt){
            if (evt.target.nodeName === "SPAN" || evt.target.nodeName === "DIV" || evt.target.nodeName === "TD") {
                // 当前操作的ID
                _self.selectId = $(this).closest(".layui-form").attr("lay-id");

                _self.onBeforeSelect(evt);
                clearEventBubble(evt);
            }
        });
        // 鼠标移动
        $(document).mousemove(function(evt){
            _self.onSelect(evt);
            // clearEventBubble(evt);
        });
        // 鼠标松开
        $(document).mouseup(function(evt){
            if (_self.isSelect) {
                _timeoutID && window.clearTimeout(_timeoutID);
                _timeoutID = window.setTimeout(function () {
                    _self.endFun();
                }, 500);
            }

            _self.onEnd();
        });
    };

    RegionSelect.prototype.onBeforeSelect = function(evt){

        if(!document.getElementById("selContainer")){
            this.selectDiv = $("<div></div>");
            this.selectDiv.attr("id", "selContainer");
            this.selectDiv.addClass("sel-container");
            this.selectDiv.css({
                "width":"0px",
                "height":"0px",
                "display":"none"
            });
            $(document.body).append(this.selectDiv);
        }else{
            this.selectDiv = $("#selContainer");
        }

        this.startX = posXY(evt).x;
        this.startY = posXY(evt).y;

        this.isSelect = true;
    };

    RegionSelect.prototype.onSelect = function(evt){
        var _self = this;
        if(_self.isSelect){

            if(_self.selectDiv.css("display") === "none") _self.selectDiv.css("display", "");

            var posX = posXY(evt).x;
            var poxY = posXY(evt).y;

            _self.selectDiv.css("left", Math.min(posX, this.startX)+'px');
            _self.selectDiv.css("top", Math.min(poxY, this.startY)+'px');
            _self.selectDiv.css("width", Math.abs(posX - this.startX)+'px');
            _self.selectDiv.css("height", Math.abs(poxY - this.startY)+'px');

            var regionList = _self.regions[_self.id];
            for(var i=0; i< regionList.length; i++){
                var r = regionList[i], sr = _self.innerRegion(_self.selectDiv,r);
                if(sr  &&  !r.hasClass(_self.selectedClass)){
                    r.addClass(_self.selectedClass);
                    _selectedRegions[_self.id].push(r);
                }else if(!sr  &&  r.hasClass(_self.selectedClass)){
                    r.removeClass(_self.selectedClass);
                    _selectedRegions[_self.id].remove(r);
                }
            }
        }
    };

    RegionSelect.prototype.onEnd = function(){
        if(this.selectDiv){
            this.selectDiv.css("display", "none")
        }
        this.isSelect = false;
    };

    RegionSelect.prototype.endFun = function(){
        var _self = this;

        if (!_callbackFun[_self.selectId]) {
            return false;
        }

        if (typeof (_callbackFun[_self.selectId]) === "function") {
            // 返回选中的表格数据
            let returnData = [];
            if (_selectedRegions[_self.selectId]) {
                for(var i=0; i < _selectedRegions[_self.selectId].length;i++){
                    let index = _selectedRegions[_self.selectId][i].index();
                    if (_self.data[_self.selectId][index]) {
                        returnData.push(_self.data[_self.selectId][index]);
                    }
                }
            }
            return _callbackFun[_self.selectId](returnData, _selectedRegions[_self.selectId]);
        }

        return _callbackFun[_self.selectId](_selectedRegions[_self.selectId]);
    };

    // 判断一个区域是否在选择区内
    RegionSelect.prototype.innerRegion = function(selDiv, region){
        var s_top = parseInt(selDiv.css("top"));
        var s_bottom = s_top + parseInt(selDiv.height()) + 2;

        var r_top = parseInt(region.offset().top);
        var r_bottom = r_top + parseInt(region.height());

        var t = Math.max(s_top, r_top);
        var b = Math.min(s_bottom, r_bottom);

        return (b > t + 2) ? region : null
    };

    let active = {
        render:function(tableObj, callbackFun){
            return new RegionSelect(tableObj, callbackFun);
        }
    };

    exports("tableDragSelect", active);
});